home *** CD-ROM | disk | FTP | other *** search
- /* ser.c */
-
- /* heavily borrowed from my program to control the ic-735 via rs-232 */
- #include <exec/types.h>
- #include <exec/exec.h>
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <graphics/text.h>
- #include <devices/serial.h>
- #include <ctype.h>
- #include <libraries/dos.h>
- #include "mb.h"
- #include "amiga.h"
- extern short debug;
- extern char *speed;
- extern struct Window *mywindow;
- extern long keybit,readbit,windbit;
- extern char tmpstr[],optflags[];
- extern short done_flag;
- /* */
- long getbits;
- ULONG class;
- USHORT code;
-
- /* msg structure for GetMsg() */
- extern struct IntuiMessage *NewMessage;
-
- /* declarations for the serial stuff */
- struct IOExtSer *Ser_Read;
- unsigned char rs_in[2];
- struct IOExtSer *Ser_Write;
- unsigned char rs_out[2];
- int serflags;
- short tapr_flag = 0; /* Using tapr upgrade? */
- long BaudRate = 9600L;
-
- /* defaults to "serial.device" but user can change it if they have a
- multi-serial card
- */
- extern UBYTE *ser_dev_name;
- extern long unit; /* defaults to zero, but can be changed */
- initser()
- {
- long error;
- if(ser_dev_name == 0L)ser_dev_name = (UBYTE *)SERIALNAME;
- Ser_Read = (struct IOExtSer *)AllocMem
- ((long)sizeof(*Ser_Read),
- (long)MEMF_PUBLIC|MEMF_CLEAR);
- serflags = Ser_Read->io_SerFlags =
- SERF_SHARED | SERF_XDISABLED | SERF_7WIRE;
- Ser_Read->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
- if(OpenDevice(ser_dev_name,unit,(struct IORequest *)Ser_Read,0L)) {
- puts("Cant open Read device\n");
- DeletePort(Ser_Read->IOSer.io_Message.mn_ReplyPort);
- FreeMem(Ser_Read,(long)sizeof(*Ser_Read));
- return(1);
- }
- Ser_Read->IOSer.io_Command = CMD_READ;
- Ser_Read->IOSer.io_Length = 1L;
- Ser_Read->IOSer.io_Data = (APTR) &rs_in[0];
-
- Ser_Write = (struct IOExtSer *)AllocMem
- ((long)sizeof(*Ser_Write),
- (long)MEMF_PUBLIC|MEMF_CLEAR);
- Ser_Write->io_SerFlags = SERF_SHARED | SERF_XDISABLED | SERF_7WIRE;
- Ser_Write->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
- if(OpenDevice(ser_dev_name,unit,(struct IORequest *)Ser_Write,0L)) {
- puts("Cant open Write device\n");
- getout:
- CloseDevice((struct IORequest *)Ser_Read);
- DeletePort(Ser_Write->IOSer.io_Message.mn_ReplyPort);
- FreeMem(Ser_Write,(long)sizeof(*Ser_Write));
- DeletePort(Ser_Read->IOSer.io_Message.mn_ReplyPort);
- FreeMem(Ser_Read,(long)sizeof(*Ser_Read));
- return(1);
- }
- Ser_Read->io_TermArray.TermArray0 = 0x0L;
- Ser_Read->io_TermArray.TermArray1 = 0x0L;
- Ser_Write->IOSer.io_Command = CMD_WRITE;
- Ser_Write->IOSer.io_Length = 1L;
- Ser_Write->IOSer.io_Data = (APTR) &rs_out[0];
- Ser_Read->IOSer.io_Command = SDCMD_SETPARAMS;
- Ser_Read->io_SerFlags = SERF_SHARED | SERF_XDISABLED | SERF_7WIRE;
- if((error = DoIO((struct IORequest *)Ser_Read)) != 0) {
- sprintf(tmpstr,"error 0 #%ld from setcommand in seric.c\n",error);
- ttputs(tmpstr);
- goto getout;
- }
- /* Set the break time which is required if the TNC is used in transparent
- mode. It is probably only necessary to do this once for Ser_Read but
- I do Ser_Write as well just in case. The default appears to be
- 250000.
- */
- Ser_Read->io_BrkTime = 300000L;
- Ser_Write->io_BrkTime = 300000L;
- Ser_Read->io_Baud = BaudRate;
- if((error = DoIO((struct IORequest *)Ser_Read)) != 0) {
- sprintf(tmpstr,"error 1 #%ld from setcommand in seric.c\n",error);
- ttputs(tmpstr);
- goto getout;
- }
- Ser_Write->IOSer.io_Command = SDCMD_SETPARAMS;
- if((error = DoIO((struct IORequest *)Ser_Write)) != 0) {
- sprintf(tmpstr,"error W #%ld from setcommand in seric.c\n",error);
- ttputs(tmpstr);
- goto getout;
- }
- Ser_Read->io_ReadLen = 8;
- Ser_Read->io_WriteLen = 8;
- if((error = DoIO((struct IORequest *)Ser_Read)) != 0) {
- sprintf(tmpstr,"error 2 #%ld from setcommand in seric.c\n",error);
- ttputs(tmpstr);
- goto getout;
- }
- Ser_Read->io_RBufLen = 4096L;
- if((error = DoIO((struct IORequest *)Ser_Read)) != 0) {
- sprintf(tmpstr,"error 3 #%ld from setcommand in seric.c\n",error);
- ttputs(tmpstr);
- goto getout;
- }
- Ser_Read->IOSer.io_Command = CMD_READ;
-
- BeginIO((struct IORequest *)Ser_Read);
-
- readbit = (1L << Ser_Read->IOSer.io_Message.mn_ReplyPort->mp_SigBit);
- return(0);
- }
-
- cleanser()
- {
- AbortIO((struct IORequest *)Ser_Read);
- AbortIO((struct IORequest *)Ser_Write);
- CloseDevice((struct IORequest *)Ser_Read);
- CloseDevice((struct IORequest *)Ser_Write);
- DeletePort(Ser_Write->IOSer.io_Message.mn_ReplyPort);
- FreeMem(Ser_Write,(long)sizeof(*Ser_Write));
- DeletePort(Ser_Read->IOSer.io_Message.mn_ReplyPort);
- FreeMem(Ser_Read,(long)sizeof(*Ser_Read));
- }
-
- /*
- Read one char from the serial port.
- If rflag is non-null then don't start the next read IO.
- This is only used in YAPP and is turned off when it is done.
- */
- short rflag = 0;
- extern long serfirst;
- unsigned char rdchar()
- {
- unsigned char c;
- long waitbits;
-
- waitbits = windbit | readbit;
- /* There might already be an unread char at the serial port */
- serfirst = 0L;
- if(CheckIO((struct IORequest *)Ser_Read)) {
- Wait(readbit);
- serfirst |= readbit;
- }
- while(1) {
- if(serfirst) {
- getbits = serfirst;
- serfirst = 0L;
- }
- else {
- getbits = Wait(waitbits);
- }
- if(windbit & getbits) {
- while(NewMessage = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
- class = NewMessage->Class;
- code = NewMessage->Code;
- switch( class ) {
- case CLOSEWINDOW:
- if(done_flag)done(1);
- break;
- default:
- ReplyMsg((struct Message *) NewMessage );
- } /* end of switch (class) */
- }
- }
- if(readbit & getbits) {
- WaitIO((struct IORequest *)Ser_Read);
- c = rs_in[0];
- if(tapr_flag)c &= 0177;
- Ser_Read->IOSer.io_Command = CMD_READ;
- Ser_Read->IOSer.io_Length = 1L;
- Ser_Read->IOSer.io_Data = (APTR) &rs_in[0];
- if(!rflag)BeginIO((struct IORequest *)Ser_Read);
- return(c);
- }
- }
- }
- /* This flag is used to allow the program to detect when a user has
- sent data while we are sending them info. This will be interpreted
- as an interrupt.
- The code looking for an interrupt must clear the flag first and then
- test it where appropriate.
- */
- /* send character to the serial port */
- schar(ch)
- int ch;
- {
-
- Ser_Write->IOSer.io_Command = CMD_WRITE;
- Ser_Write->IOSer.io_Length = 1L;
- Ser_Write->IOSer.io_Data = (APTR) &rs_out[0];
- rs_out[0] = ch;
- DoIO((struct IORequest *)Ser_Write);
- }
-
- /* Allows program to Check Carrier Detect and/or DSR */
- getserstat()
- {
- Ser_Write->IOSer.io_Command = SDCMD_QUERY;
- DoIO((struct IORequest *)Ser_Write);
- return(Ser_Write->io_Status);
- }
-
- /* send the command string in s */
- sends(s)
- unsigned char *s;
- {
- register unsigned char *p;
- register short i;
-
- i = 0;
- p = s;
- /* Count the number of chars in the string */
- while(*p++)i++;
- if(i == 0)return;
- Ser_Write->IOSer.io_Command = CMD_WRITE;
- Ser_Write->IOSer.io_Length = i;
- Ser_Write->IOSer.io_Data = (APTR) s;
- DoIO((struct IORequest *)Ser_Write);
- }
- extern short block_cancel;
- sendblock(s,l)
- unsigned char *s;
- int l;
- {
- register char ch;
- extern unsigned char ichar;
- extern struct IOStdReq *Con_Read;
-
- Ser_Write->IOSer.io_Command = CMD_WRITE;
- Ser_Write->IOSer.io_Length = l;
- Ser_Write->IOSer.io_Data = (APTR) s;
- DoIO((struct IORequest *)Ser_Write);
- if(CheckIO((struct IORequest *)Con_Read)) {
- Wait(keybit);
- WaitIO((struct IORequest *)Con_Read);
- ch = ichar;
- Con_Read->io_Data = (APTR)&ichar;
- Con_Read->io_Command = CMD_READ;
- Con_Read->io_Length = 1;
- SendIO((struct IORequest *)Con_Read);
- if(ch == '\033') {
- ttputs("sendblock\n");
- }
- if(ch == achar) {
- block_cancel = 1;
- port->mode = forced;
- AbortIO((struct IORequest *)Ser_Read);
- restart();
- return(1);
- }
- }
- return(0);
- }
- breakport()
- {
- Ser_Write->IOSer.io_Command = SDCMD_BREAK;
- DoIO((struct IORequest *)Ser_Write);
- }
- rdblock(p,l)
- char *p;
- int l;
- {
- register int i;
-
- /* Negative length indicates read a null-terminated string of maximum
- length -l including the null.
- */
- if(l < 0) {
-
- /* Looking for a null-terminated string is not supported by the
- ibmser.device for the GoldenGate II card and, as Dan Babcock
- who wrote ibmser.device has told me, it is an inherently
- unreliable way to read because the null byte could get lost.
- So use EOFMODE and ask for the maximum permissible length.
- */
- Ser_Read->io_SerFlags |= SERF_EOFMODE;
- Ser_Read->IOSer.io_Command = CMD_READ;
- Ser_Read->IOSer.io_Length = (long) -l;
- Ser_Read->IOSer.io_Data = (APTR) p;
- BeginIO((struct IORequest *)Ser_Read);
- }
- else {
- Ser_Read->IOSer.io_Command = CMD_READ;
- Ser_Read->IOSer.io_Length = (long)l;
- Ser_Read->IOSer.io_Data = (APTR) p;
- BeginIO((struct IORequest *)Ser_Read);
- }
- i = rdwait();
- if(l < 0) {
- Ser_Read->io_SerFlags &= ~SERF_EOFMODE;
- }
- return(i == 0);
- }
- restart()
- {
- rflag = 0;
- Ser_Read->IOSer.io_Command = CMD_READ;
- Ser_Read->IOSer.io_Length = 1L;
- Ser_Read->IOSer.io_Data = (APTR) &rs_in[0];
- BeginIO((struct IORequest *)Ser_Read);
- }
- rdwait()
- {
- long waitbits;
- register char ch;
- extern unsigned char ichar;
- extern struct IOStdReq *Con_Read;
-
- waitbits = windbit | readbit | keybit;
- while(1) {
- getbits = Wait(waitbits);
- if(windbit & getbits) {
- while(NewMessage = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
- class = NewMessage->Class;
- code = NewMessage->Code;
- switch( class ) {
- case CLOSEWINDOW:
- if(done_flag)done(1);
- break;
- default:
- ReplyMsg((struct Message *) NewMessage );
- } /* end of switch (class) */
- }
- }
- if(keybit & getbits) {
- WaitIO((struct IORequest *)Con_Read);
- ch = ichar;
- Con_Read->io_Data = (APTR)&ichar;
- Con_Read->io_Command = CMD_READ;
- Con_Read->io_Length = 1;
- SendIO((struct IORequest *)Con_Read);
- if(ch == '\033') {
- ttputs("rdwait\n");
- }
- if(ch == achar) {
- port->mode = forced;
- block_cancel = 1;
- AbortIO((struct IORequest *)Ser_Read);
- restart();
- return(0);
- }
- }
- if(readbit & getbits) {
- WaitIO((struct IORequest *)Ser_Read);
- return((short)Ser_Read->IOSer.io_Actual);
- }
- }
- }
-